import sys
import logging
from lxml import etree
import sqlalchemy, sqlalchemy.types
from rest4databases.lib.base import *
from rest4databases.lib.databases import TableNotExistException

log = logging.getLogger(__name__)

class TablesController(BaseController):
    """REST Controller styled on the Atom Publishing Protocol"""
    # To properly map this controller, ensure your config/routing.py file has
    # a resource setup:
    #     map.resource('table', 'tables')


    def index(self, format='html'):
        """GET /tables: All items in the collection."""
        # url_for('tables')
        class Table(object):
            def __init__(self, name, url):
                self.name = name
                self.url = url
        c.tables = [Table(t, '/db/tables/%s' % t) for t in g.database.metadata.table_iterator(reverse=False)]
        response.headers['Content-Type'] = 'text/xml; charset=utf-8'
        return render('/tables/list.mako')

    def getDefinition(self, table):
        try:
            c.table = g.database.getDefinition(table)
            response.headers['Content-Type'] = 'text/xml; charset=utf-8'
            return render('/tables/definition.mako')
        except TableNotExistException:
            abort(404)

    def create(self):
        """POST /tables: Create a new item."""
        # url_for('tables')
        try:
            content = request.body.read(int(request.environ['CONTENT_LENGTH']))
            table = self._XMLToDict(content)
            g.database.createTable(table[0], table[1])
            del response.headers['Content-Type']
            response.status_code = 201
            return "/db/tables/" + table[0]['name']
        except etree.XMLSyntaxError:
            print content
            abort(400)

    def new(self, format='html'):
        """GET /tables/new: Form to create a new item."""
        # url_for('new_table')
        pass

    def update(self, id):
        """PUT /tables/id: Update an existing item."""
        # Forms posted to this method should contain a hidden field:
        #    <input type="hidden" name="_method" value="PUT" />
        # Or using helpers:
        #    h.form(h.url_for('table', id=ID),
        #           method='put')
        # url_for('table', id=ID)
        pass

    def delete(self, tablename):
        """DELETE /tables/id: Delete an existing item."""
        # Forms posted to this method should contain a hidden field:
        #    <input type="hidden" name="_method" value="DELETE" />
        # Or using helpers:
        #    h.form(h.url_for('table', id=ID),
        #           method='delete')
        # url_for('table', id=ID)
        g.database.dropTable(tablename)
        del response.headers['Content-Type']
        response.status_code = 204
        return

    def show(self, id, format='html'):
        """GET /tables/id: Show a specific item."""
        # url_for('table', id=ID)
        pass

    def edit(self, id, format='html'):
        """GET /tables/id;edit: Form to edit an existing item."""
        # url_for('edit_table', id=ID)
        pass

    def _XMLToDict(self, xml):
#[
#{"name":"id", "type":"integer", "primarykey": True, "autoincrement":True}
#,{"name":"name", "type":"string", "nullable":False}
# ]
        tree = etree.fromstring(xml)
        name = tree.get('name')
        updated = tree.get('updated')
        created = tree.get('created')
        fields_list = []
        id_fields = tree.xpath('/table/field[@name="id"]')
        for id_field in id_fields:
            tree.remove(id_field)
        fields  = tree.xpath('/table/field')
        for field in fields:
            field_dict = {}
            field_dict['name'] = field.get('name')
            field_dict['type'] = field.get('type')
            if field.get('primarykey') is not None:
                field_dict['primarykey'] = True
            if field.get('autoincrement') is not None:
                field_dict['autoincrement'] = True
            if field.get('default') is not None:
                field_dict['default'] = field.get('default')
            if field.get('unique') is not None:
                field_dict['unique'] = True
            if field.get('index') is not None:
                field_dict['index'] = True
            fields_list.append(field_dict)
        return ({'name': name, 'created': created, 'updated': updated}, fields_list)